package yang.java8.newTimeApi;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class Test {

	public static void main(String[] args) {
		test8();
	}
	
	public static void test1() {
		LocalDate firstDayOfThisYear = LocalDate.now().withDayOfYear(1).withDayOfMonth(1);
		LocalDate programmersDay = firstDayOfThisYear.plusDays(255);
		System.out.println(programmersDay);
		programmersDay = firstDayOfThisYear.plus(Period.ofDays(255));
		System.out.println(programmersDay);

		TemporalAdjuster adj1 = w -> {
			LocalDate result = (LocalDate) w;
			int i = 1;
			while (i++ <= 255) {
				result = result.plusDays(1);
			}
			return result;
		};
		programmersDay = firstDayOfThisYear.with(adj1);
		System.out.println(programmersDay);

		adj1 = TemporalAdjusters.ofDateAdjuster(w -> {
			int i = 1;
			while (i++ <= 256) {
				w = w.plusDays(1);
			}
			return w;
		});

		programmersDay = firstDayOfThisYear.with(adj1);
		System.out.println(programmersDay);
	}
	
	public static void test2() {
		LocalDate date1 = LocalDate.of(2000, 2, 29);
		LocalDate date2 = date1.plusYears(1);
		LocalDate date3 = date1.plusYears(4);
		LocalDate date4 = date1.plusYears(1).plusYears(1).plusYears(1).plusYears(1);
		System.out.println(date1);
		System.out.println(date2);
		System.out.println(date3);
		System.out.println(date4);
	}
	
	public static void test3() {
		LocalDate today = LocalDate.now();
		LocalDate nextWordDay = today.with(next(w -> w.getDayOfWeek().getValue() < 6));
	}
	
	public static TemporalAdjuster next(Predicate<LocalDate> p) {
		return (temporal) -> {
            LocalDate output = (LocalDate) temporal;
            while (!p.test(output)) {
            	output = output.plusDays(1);
			}
            return temporal.with(output);
        };
	}
	
	public static void test4() {
		LocalDate date = LocalDate.of(2013, 3, 1);
		LocalDate nextDate = date.plusMonths(1);
		while(date.isBefore(nextDate)) {
			printDate(date);
			date = date.plusDays(1);
		}
	}
	
	public static void printDate(LocalDate date) {
		if (date.getDayOfMonth() == 1) {
			// 当月第一天
			for (int i = 1; i < date.getDayOfWeek().getValue(); i++) {
				System.out.print("\t");
			}
		}
		if (date.getDayOfWeek() == DayOfWeek.MONDAY) {
			System.out.println();
		}
		System.out.print(date.getDayOfMonth() + "\t");
	}
	
	public static void test5() {
		LocalDate now = LocalDate.now();
		LocalDate past = LocalDate.of(1990, 1, 1);
		long p = past.until(now, ChronoUnit.DAYS);
		System.out.println(p);
	}
	
	public static void test6() {
		LocalDate centryBegin = LocalDate.of(2000, 1, 1);
		LocalDate nextCentry = LocalDate.of(2100, 1, 1);
		while(centryBegin.isBefore(nextCentry)) {
			centryBegin = centryBegin.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
			System.out.println(centryBegin);
		}
	}
	
	public static void test7() {
		
	}
	
	public static void test8() {
		ZonedDateTime time = ZonedDateTime.now();
		Stream<String> stream = ZoneId.getAvailableZoneIds().stream();
		stream.forEach(v -> {
			ZoneOffset off = time.withZoneSameInstant(ZoneId.of(v)).getOffset();
			System.out.println(off + v);
		});
	}
	
	public static void test10() {
		LocalDate day = LocalDate.of(2014, 5, 10);
		LocalTime time = LocalTime.of(15, 5);
		ZonedDateTime los = ZonedDateTime.of(day, time, ZoneId.of("America/Los_Angeles"));
		ZonedDateTime frank = los.plusHours(10).plusMinutes(50)
				.withZoneSameInstant(ZoneId.of("Europe/Berlin"));
		System.out.println(los);
		System.out.println(frank);
		
		Duration duration = Duration.between(los.toInstant(), frank.toInstant());
        System.out.println(duration);
	}
	
	public static void test12() {
		LocalDate day = LocalDate.of(2014, 5, 10);
		LocalTime time = LocalTime.of(15, 5);
		ZonedDateTime los = ZonedDateTime.of(day, time, ZoneId.of("America/Los_Angeles"));// -7时区
		ZonedDateTime frank = ZonedDateTime.of(day, time, ZoneId.of("Europe/Berlin"));// +2时区
		Duration duration = Duration.between(los.toInstant(), frank.toInstant());;
		System.out.println(duration.getSeconds() / 60);
	}

}
